home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Atari Forever 4
/
Atari Forever 4.zip
/
Atari Forever 4.iso
/
PD_THEMA
/
EDITOREN
/
QED_397
/
SOURCEN
/
UMBRUCH.C
< prev
next >
Wrap
C/C++ Source or Header
|
1998-03-14
|
11KB
|
449 lines
#include "global.h"
#include "ausgabe.h"
#include "block.h"
#include "clipbrd.h"
#include "edit.h"
#include "scroll.h"
#include "set.h"
#include "tasten.h"
#include "text.h"
#include "windows.h"
#include "umbruch.h"
/* Muessen am Anfang jeden Umbruchs gesetzt werden */
LOCAL BOOLEAN tab;
LOCAL WORD tab_size, lineal_len;
LOCAL SET umbruch_set;
LOCAL BOOLEAN Absatz (LINEP col);
LOCAL BOOLEAN too_short (TEXTP t_ptr, LINEP col, LONG y);
LOCAL BOOLEAN too_long (TEXTP t_ptr, LINEP col, LONG y);
VOID save_absatz(TEXTP t_ptr)
/* Es werden LZ und TABs am Absatzende gelöscht */
/* und im Absatz hinzugefügt */
{
BOOLEAN action = FALSE;
WORD i;
UBYTE c;
LINEP lauf;
setcpy(umbruch_set,t_ptr->loc_opt->umbruch_set);/* !! Muß gesetzt werden !! */
setincl(umbruch_set,' '); /* wenigstens das */
lauf = FIRST(&t_ptr->text);
while (!IS_TAIL(lauf))
{
if (lauf->info&ABSATZ) /* Absatz => LZ und TAB löschen */
{
for (i=lauf->len; (--i)>=0 ; )
{
c = TEXT(lauf)[i];
if (c!=' ' && c!='\t') break;
}
i++;
if (i<lauf->len) /* Zeile verkürzen */
{
REALLOC(&lauf,i,i-lauf->len);
action = TRUE;
}
}
else /* Nicht Absatz => LZ anhängen */
{
c = TEXT(lauf)[lauf->len-1];
if (!setin(umbruch_set,c) && lauf->len<MAX_LINE_LEN)
{
*REALLOC(&lauf,lauf->len,1) = ' ';
action = TRUE;
}
}
NEXT(lauf);
}
if (action) /* Es wurde etwas verändert */
{
make_chg(t_ptr->link,TOTAL_CHANGE,0);
t_ptr->moved++;
lauf = t_ptr->cursor_line = get_line(&t_ptr->text,t_ptr->ypos);
if (t_ptr->xpos>lauf->len)
{
t_ptr->xpos = lauf->len;
make_chg(t_ptr->link,POS_CHANGE,0);
}
}
}
LOCAL BOOLEAN Absatz(LINEP col)
/* TRUE : Die Zeile ist die letzte Zeile eines Absatz */
/* FALSE : sonst */
{
WORD col_len = col->len;
UBYTE c = TEXT(col)[col_len-1];
return (col_len==0 || IS_LAST(col) || !setin(umbruch_set,c));
}
VOID make_absatz(TEXTP t_ptr)
/* Absatzmarkierungen anbringen oder löschen */
{
LINEP lauf;
setcpy(umbruch_set,t_ptr->loc_opt->umbruch_set);/* !! Muß gesetzt werden !! */
setincl(umbruch_set,' '); /* wenigstens das */
lauf = FIRST(&t_ptr->text);
if (t_ptr->loc_opt->umbrechen)
while (!IS_TAIL(lauf))
{
if (Absatz(lauf))
lauf->info |= ABSATZ;
else
lauf->info &= (~ABSATZ); /* z.B. CR setzt immer Bit */
NEXT(lauf);
}
else
while (!IS_TAIL(lauf))
{
lauf->info &= (~ABSATZ);
NEXT(lauf);
}
}
LOCAL WORD long_brk(LINEP col)
/* Zeile ist zu lang. Wo soll sie abgebrochen werden (mind. ein Wort) */
{
WORD off, pos;
UBYTE c, *str;
off = col_offset(col);
pos = InterPos(lineal_len,col,tab,tab_size);
str = TEXT(col)+pos;
pos--;
c = *(--str);
if (!setin(umbruch_set,c))
while (pos>off && setin(umbruch_set,c)) /* Wortende suchen */
{
pos--;
c = *(--str);
}
while (pos>off && !setin(umbruch_set,c)) /* Wortanfang suchen */
{
pos--;
c = *(--str);
}
if (pos<=off) /* nach rechts */
{
pos = InterPos(lineal_len,col,tab,tab_size);
str = TEXT(col)+pos;
c = *str++;
while (pos<=col->len && setin(umbruch_set,c)) /* Wortanf suchen */
{
pos++;
c = *str++;
}
while (pos<=col->len && !setin(umbruch_set,c)) /* Wortende suchen */
{
pos++;
c = *str++;
}
while (pos<=col->len && setin(umbruch_set,c)) /* Wortanf suchen */
{
pos++;
c = *str++;
}
if (pos>=col->len)
return 0; /* nichts machen */
}
else
pos++;
return pos;
}
LOCAL WORD short_brk(LINEP col, WORD len)
/* Einer Zeile fehlen Zeichen, sie ist jetzt im Bild len lang */
/* Wo soll der Nachfolger (col) hochgezogen werden (mind. ein Wort) */
{
UBYTE *str, c;
WORD pos, merk_pos;
pos = col_offset(col);
str = TEXT(col)+pos;
merk_pos = -1;
if (!tab)
{
while (TRUE)
{
if (pos>=col->len) return col->len; /* ganze Zeile */
c = *str++;
pos++;
len++;
if (len>lineal_len) break; /* jetzt reichts */
if (setin(umbruch_set,c))
merk_pos = pos;
}
}
else
{
WORD tabH;
tabH = tab_size-(len%tab_size);
while (TRUE)
{
if (pos>=col->len) return col->len; /* ganze Zeile */
c = *str++;
pos++;
if (c=='\t')
{
len += tabH;
tabH = tab_size;
}
else
{
len++;
if ((--tabH)==0) tabH = tab_size;
}
if (len>lineal_len) break; /* jetzt reichts */
if (setin(umbruch_set,c))
merk_pos = pos;
}
}
if (merk_pos>0) pos = merk_pos;
else pos = 0; /* nichts zu machen */
return(pos);
}
/* !!! cursor_line muß hinterher entsprechend ypos gesetzt werden !!! */
LOCAL BOOLEAN too_long(TEXTP t_ptr, LINEP col, LONG y)
{
WORD i, len, off;
BOOLEAN absatz, weiter, changed;
changed = FALSE;
weiter = FALSE;
while (BildLen(col,t_ptr->loc_opt->tab,t_ptr->loc_opt->tabsize)>lineal_len) /* Zeile zu lang */
{
i = long_brk(col); /* wo abbrechen */
if (i==0)
{
weiter = FALSE;
break;
}
absatz = col->info&ABSATZ;
len = col->len-i; /* soviel abschneiden */
if (absatz || col->nachf->len+len >= MAX_LINE_LEN) /* col_split */
{
LINEP help;
col_split(&col,i);
t_ptr->text.lines++;
if (t_ptr->ypos>y) t_ptr->ypos++;
help = col->nachf;
off = einrucken(&help);
if (t_ptr->ypos==y && t_ptr->xpos>i) /* Cursor umbrechen */
{
t_ptr->ypos++;
t_ptr->xpos -= (i-off);
}
weiter = TRUE;
}
else /* Text rumschieben */
{
LINEP help = col->nachf;
off = col_offset(help);
INSERT(&help,off,len,TEXT(col)+i); /* Next verlängern */
REALLOC(&col,i,-len); /* Zeile kürzen */
if (t_ptr->ypos==y+1 && t_ptr->xpos>off) /* Cursor verschieben */
{
t_ptr->xpos += len;
}
if (t_ptr->ypos==y && t_ptr->xpos>i) /* Cursor umbrechen */
{
t_ptr->ypos++;
t_ptr->xpos -= (i-off);
}
weiter = FALSE;
}
NEXT(col); /* nächste Zeile zu lang? */
y++;
changed = TRUE;
}
if (weiter) too_short(t_ptr,col,y); /* nächste Zeile zu kurz? */
return (changed);
}
/* !!! cursor_line muß hinterher entsprechend ypos gesetzt werden !!! */
LOCAL BOOLEAN too_short(TEXTP t_ptr, LINEP col, LONG y)
{
WORD len, off;
LINEP next_col;
BOOLEAN changed;
changed = FALSE;
tab = t_ptr->loc_opt->tab;
tab_size = t_ptr->loc_opt->tabsize;
while (BildLen(col,t_ptr->loc_opt->tab,t_ptr->loc_opt->tabsize)<lineal_len && !(col->info&ABSATZ) && col->nachf->len>0)
{
next_col = col->nachf;
len = short_brk(next_col,BildLen(col,t_ptr->loc_opt->tab,t_ptr->loc_opt->tabsize));
if (len==0) break; /* nichts zu machen */
off = col_offset(next_col);
if (len==next_col->len) /* ganze Zeile hochziehen */
{
if (t_ptr->ypos==y+1) /* Cursor hochziehen */
{
t_ptr->ypos--;
t_ptr->xpos += (col->len-off);
}
if (t_ptr->ypos>y+1) t_ptr->ypos--;
REALLOC(&next_col,0,-off);
col_concate(&col);
t_ptr->text.lines--; /* gleiche Zeile nochmal */
}
else /* teilweise hochziehen */
{
len -= off;
if (t_ptr->ypos==y+1 && t_ptr->xpos>=off)
{
if (t_ptr->xpos<off+len)
{
t_ptr->ypos--;
t_ptr->xpos += (col->len-off);
}
else
t_ptr->xpos -= len;
}
INSERT(&col,col->len,len,TEXT(next_col)+off);/* Zeile verlängern */
REALLOC(&next_col,off,-len); /* Zeile verkürzen */
col = next_col; /* nächste Zeile weiter */
y++;
}
changed = TRUE;
}
return(changed);
}
VOID umbruch(TEXTP t_ptr)
{
LONG y = t_ptr->ypos;
setcpy(umbruch_set,t_ptr->loc_opt->umbruch_set);/* !! Muß gesetzt werden !! */
setincl(umbruch_set,' '); /* wenigstens das */
tab = t_ptr->loc_opt->tab;
tab_size = t_ptr->loc_opt->tabsize;
lineal_len = t_ptr->loc_opt->lineal_len;
if (too_long(t_ptr, t_ptr->cursor_line, t_ptr->ypos))
{
t_ptr->cursor_line = get_line(&t_ptr->text,t_ptr->ypos);
t_ptr->moved++;
make_chg(t_ptr->link,POS_CHANGE,0);
make_chg(t_ptr->link,TOTAL_CHANGE,y);
clr_undo();
}
else if (too_short(t_ptr, t_ptr->cursor_line, t_ptr->ypos))
{
t_ptr->cursor_line = get_line(&t_ptr->text,t_ptr->ypos);
t_ptr->moved++;
make_chg(t_ptr->link,POS_CHANGE,0);
make_chg(t_ptr->link,TOTAL_CHANGE,y);
clr_undo();
}
}
VOID format(TEXTP t_ptr)
{
LINEP lauf;
LONG y, start_y;
BOOLEAN change;
setcpy(umbruch_set,t_ptr->loc_opt->umbruch_set);/* !! Muß gesetzt werden !! */
setincl(umbruch_set,' '); /* wenigstens das */
tab = t_ptr->loc_opt->tab;
tab_size = t_ptr->loc_opt->tabsize;
lineal_len = t_ptr->loc_opt->lineal_len;
change = FALSE;
lauf = t_ptr->cursor_line;
y = t_ptr->ypos;
if (y)
{
y--;
VORG(lauf);
while ((y>0) && (!(lauf->info&ABSATZ)))
{
y--;
VORG(lauf);
}
if (y)
{
y++;
NEXT(lauf);
}
}
/* lauf zeigt jetzt auf die erste Zeile des Absatz */
start_y = y;
lauf = lauf->vorg; /* Einen davor, weil akt. Zeile geändert wird */
while(TRUE)
{
if (!too_long(t_ptr, lauf->nachf,y))
{
if (too_short(t_ptr, lauf->nachf,y))
change = TRUE;
}
else
change = TRUE;
y++;
NEXT(lauf);
if (lauf->info&ABSATZ) break;
}
if (change)
{
t_ptr->cursor_line = get_line(&t_ptr->text,t_ptr->ypos);
t_ptr->moved++;
make_chg(t_ptr->link,POS_CHANGE,0);
make_chg(t_ptr->link,TOTAL_CHANGE,start_y);
clr_undo();
}
}
VOID total_format(TEXTP t_ptr)
{
LINEP lauf;
LONG y;
BOOLEAN change;
setcpy(umbruch_set,t_ptr->loc_opt->umbruch_set);/* !! Muß gesetzt werden !! */
setincl(umbruch_set,' '); /* wenigstens das */
tab = t_ptr->loc_opt->tab;
tab_size = t_ptr->loc_opt->tabsize;
lineal_len = t_ptr->loc_opt->lineal_len;
change = FALSE;
Busy_mouse();
lauf = FIRST(&t_ptr->text);
y = 0;
while (!IS_TAIL(lauf))
{
/* lauf zeigt jetzt auf die erste Zeile des Absatz */
lauf = lauf->vorg; /* Einen davor, weil akt. Zeile geändert wird */
while(TRUE)
{
if (!too_long(t_ptr, lauf->nachf,y))
{
if (too_short(t_ptr, lauf->nachf,y))
change = TRUE;
}
else
change = TRUE;
y++;
NEXT(lauf);
if (lauf->info&ABSATZ) break;
}
NEXT(lauf);
}
if (change)
{
t_ptr->cursor_line = get_line(&t_ptr->text,t_ptr->ypos);
t_ptr->moved++;
make_chg(t_ptr->link,POS_CHANGE,0);
make_chg(t_ptr->link,TOTAL_CHANGE,0);
clr_undo();
}
Last_mouse();
}